﻿#define USE_NEW_APPLICATION_DATA_PATH

using System;
using System.Collections.Generic;
using System.Windows.Forms;
using ENG.EngStartQueueLib;
using Microsoft.Win32;
using System.Text;

namespace ENG.EngStartQueue
{
  static class Program
  {
    internal static string StartupFolder = null;

#if USE_NEW_APPLICATION_DATA_PATH

    internal static string ApplicationPath = 
          Application.UserAppDataPath;

#else

    internal static string ApplicationPath =
        System.IO.Path.Combine(
          Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
          System.Windows.Forms.Application.ProductName);

#endif

    internal static string QueueFile
    {
      get
      {
        return System.IO.Path.Combine(
          ApplicationPath, "esq.xml");
      }
    }
    internal static string BackupPath
    {
      get
      {
        return
        System.IO.Path.Combine(
        ApplicationPath, "Backup");
      }
    }

    internal static ENG.EngStartQueueLib.Properties.Settings LibSett
    {
      get
      {
        return ENG.EngStartQueueLib.Properties.Settings.Default;
      }
    }
    internal static ENG.EngStartQueue.Properties.Settings AppSett
    {
      get
      {
        return ENG.EngStartQueue.Properties.Settings.Default;
      }
    }

    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main(string [] args)
    {
      RegistryKey rk = RegistryAPI.GetKey( RegistryAPI.eRoot.HKCU,
        @"Software\Microsoft\Windows\CurrentVersion\Explorer\Shell folders");
      StartupFolder = (string) rk.GetValue("Startup");

      Application.EnableVisualStyles();
      Application.SetCompatibleTextRenderingDefault(false);

      if (AppSett.IsFirstStart)
      {
        string path;
        DoBackup(out path);

        AdjustLocalization(false);
        AppSett.IsFirstStart = false;
        AppSett.Save();

        MessageBox.Show("Application made initial backup into " + path,
          Application.ProductName,  MessageBoxButtons.OK, MessageBoxIcon.Error);
      }

      if ((args.Length > 0) && (args[0] == "-e"))
        Application.Run(new FrmExec());
      else if ((args.Length > 0) && (args[0] == "-s"))
      {
        FrmExec f = new FrmExec();
        f.IsSimulation = true;
        Application.Run(f);
      }
      else
        Application.Run(new FrmManager());
    }

    internal const string REG_PATH = @"Software\Microsoft\Windows\CurrentVersion\Run";

    public static void AdjustLocalization(bool throwDialogs)
    {
      ENG.EngStartQueueLib.Properties.Settings props =
        LibSett;

      string ietf = System.Globalization.CultureInfo.CurrentCulture.IetfLanguageTag;

      Counters.CultureCounters ccs = null;
      string fileName = System.IO.Path.Combine(
          Application.StartupPath,
          "CultureCounters.xml");
      try
      {
        ccs = Counters.CultureCounters.Load(
          fileName);
      }
      catch (Exception ex)
      {
        if (throwDialogs)
          MessageBox.Show(
            "Error during load of file " + fileName + ". Error: " + ex.Message + ". Update cannot be done. Aborting.");
        return;
      }

      Counters.CultureCounter c =
        ccs.GetByIetf(ietf);

      if (c == null)
      {
        if (throwDialogs)
          MessageBox.Show("Sorry, we dont know the values for the culture " + ietf +
            ". Try to find and set following values in counters for your computer in your culture nature language: " +
            Environment.NewLine +
            Environment.NewLine +
            "If you would like to participate, please send this values to the discussion forum of the product, they will "
            + " be added in next version.",
            "Unknown culture...", MessageBoxButtons.OK, MessageBoxIcon.Information);
      }
      else
      {
        props.DiscCategory = c.Counters[0].Category;
        props.DiscCounter = c.Counters[0].Counter;
        props.DiskInstance = c.Counters[0].Instance;
        props.DiscOrderMaxIsGood = c.Counters[0].isMaxGood;
        if (c.Counters[0].okValue.HasValue)
          props.DiscOkPercentage = c.Counters[0].okValue.Value;

        props.ProcesorCategory = c.Counters[1].Category;
        props.ProcesorCounter = c.Counters[1].Counter;
        props.ProcesorInstance = c.Counters[1].Instance;
        props.ProcesorOrderMaxIsGood = c.Counters[1].isMaxGood;
        if (c.Counters[1].okValue.HasValue)
          props.ProcesorOkPercentage = c.Counters[1].okValue.Value;

        System.OperatingSystem osInfo
          = System.Environment.OSVersion;

        if (throwDialogs)
          MessageBox.Show("Values updated by settings (" + c.Name + " / " + c.Language + " (" + c.Info +
            ")  from XML file.", "Updated...",
            MessageBoxButtons.OK, MessageBoxIcon.Information);
      }
    }

    internal static void LoadPerformanceMeters(
      out ENG.EngStartQueueLib.PerformanceMeter pmDisc, 
      out ENG.EngStartQueueLib.PerformanceMeter pmProc)
    {
      ENG.EngStartQueueLib.Properties.Settings sett =
        Program.LibSett;

      pmDisc = new PerformanceMeter(
        sett.DiscCategory,
        sett.DiscCounter,
        sett.DiskInstance,
        sett.DiscOrderMaxIsGood,
        sett.DiscOkPercentage);

      pmProc = new PerformanceMeter(
         sett.ProcesorCategory,
        sett.ProcesorCounter,
        sett.ProcesorInstance,
        sett.ProcesorOrderMaxIsGood,
        sett.ProcesorOkPercentage);
    }

    internal static void DoBackup(out string path)
    {
      path =
        BackupPath;

      if (!System.IO.Directory.Exists(path))
        System.IO.Directory.CreateDirectory(path);

      path = System.IO.Path.Combine(
        path,
        DateTime.Now.ToString("yyyy-MM-dd"));
      if (System.IO.Directory.Exists(path))
      {
        path += DateTime.Now.ToString("-hh-mm-ss");
      }
      System.IO.Directory.CreateDirectory(path);

      string[] files =
        System.IO.Directory.GetFiles(StartupFolder, "*.lnk");
      foreach (var fItem in files)
      {
        System.IO.File.Copy(fItem,
          System.IO.Path.Combine(path, System.IO.Path.GetFileName(fItem)));
      } // foreach (var fItem in files)

      BackupRegistry(RegistryAPI.eRoot.HKCU, "HKEY_CURRENT_USER",
        path, "HKCU");

      BackupRegistry(RegistryAPI.eRoot.HKLM, "HKEY_LOCAL_MACHINE",
        path, "HKLM");

    }

    private static void BackupRegistry(ENG.EngStartQueueLib.RegistryAPI.eRoot root, string rootText, string path, string fileName)
    {
      RegistryKey rk = RegistryAPI.GetKey(root, REG_PATH);
      string[] names = rk.GetValueNames();
      string[] values = new string[names.Length];
      for (int i = 0; i < names.Length; i++)
      {
        values[i] = (string)rk.GetValue(names[i]);
      }
      StringBuilder sb = new StringBuilder();
      sb.AppendLine("[" + rootText + "\\" + REG_PATH + "]");
      for (int i = 0; i < names.Length; i++)
      {
        sb.AppendLine(
          "\"" +
          names[i].Replace(@"""", @"\""") + 
          "\"=\"" +
          values[i].Replace(@"""", @"\""")+
          "\"");
      }
      System.IO.File.WriteAllText(
        System.IO.Path.Combine(path, fileName + ".reg"), sb.ToString());
    }
  }
}
